package cn.com.sparkle.paxos.stablestorage.model;

import java.io.IOException;
import java.util.concurrent.Callable;

import cn.com.sparkle.paxos.stablestorage.io.BufferedFileOut;
import cn.com.sparkle.paxos.util.Adler32Calc;

public class RecordBody {
	private byte[] body;
	private byte[] checksum;

	public RecordBody(byte[] body) {
		this.body = body;
		checksum = new byte[8];
		long c = Adler32Calc.calc(body, 0, 4);
		checksum[0] = (byte) (0xff & (c >> 56));
		checksum[1] = (byte) (0xff & (c >> 48));
		checksum[2] = (byte) (0xff & (c >> 40));
		checksum[3] = (byte) (0xff & (c >> 32));
		checksum[4] = (byte) (0xff & (c >> 24));
		checksum[5] = (byte) (0xff & (c >> 16));
		checksum[6] = (byte) (0xff & (c >> 8));
		checksum[7] = (byte) (0xff & c);
	}

	public RecordBody(byte[] body, byte[] checksum) {
		this.body = body;
		this.checksum = checksum;
	}

	public boolean checkSum() {
		long c = Adler32Calc.calc(body, 0, 4);
		if (c == (((long) checksum[0] << 56)
				+ ((long) (checksum[1] & 255) << 48)
				+ ((long) (checksum[2] & 255) << 40)
				+ ((long) (checksum[3] & 255) << 32)
				+ ((long) (checksum[4] & 255) << 24)
				+ ((checksum[5] & 255) << 16) + ((checksum[6] & 255) << 8) + ((checksum[7] & 255) << 0))) {
			return true;
		} else {
			return false;
		}
	}

	public byte[] getBody() {
		return body;
	}

	public byte[] getChecksum() {
		return checksum;
	}

	public void writeToStream(BufferedFileOut out, Callable<Object> callable)
			throws IOException {
		out.write(this.body, 0, this.body.length, null);
		out.write(this.checksum, 0, 8, callable);
	}
}
